'use client';

import { useToast } from '@/hooks/use-toast';
import trpc from '@/lib/trpc/client';
import { queryClient } from '@/providers/trpc-provider';
import { createAddress, updateAddress } from '@/service/actions/address';
import { addressSchema } from '@/service/actions/schema/address';
import type { AddressType } from '@/service/type/address';
import { zodResolver } from '@hookform/resolvers/zod';
import { getQueryKey } from '@trpc/react-query';
import { useState, useTransition } from 'react';
import { useForm } from 'react-hook-form';
import type { z } from 'zod';
import { PoiSearchFormItem } from '../common/poi-search-form-item';
import { Button } from '../ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '../ui/dialog';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '../ui/form';
import { Input } from '../ui/input';

type CreateAddressProps = {
  type: 'new';
  button: React.ReactNode;
};

type EditAddressProps = {
  type: 'edit';
  button: React.ReactNode;
  preData: Omit<AddressType, 'createdAt' | 'updatedAt'>;
};

const AddressForm = (
  props: (CreateAddressProps | EditAddressProps) & {
    setOpen: React.Dispatch<React.SetStateAction<boolean>>;
  },
) => {
  const { toast } = useToast();
  const [isPending, startTransition] = useTransition();
  const form = useForm<z.infer<typeof addressSchema>>({
    resolver: zodResolver(addressSchema),
    defaultValues:
      props.type === 'edit'
        ? {
            name: props.preData.name,
            phone: props.preData.phone,
            address: {
              id: props.preData.poiId,
              address: props.preData.address,
              longitude: props.preData.longitude,
              latitude: props.preData.latitude,
            },
          }
        : {
            name: '',
            phone: '',
            address: null,
          },
  });

  const onSubmit = async (data: z.infer<typeof addressSchema>) => {
    if (!data.address)
      return toast({
        variant: 'destructive',
        title: '请选择地址',
      });
    startTransition(async () => {
      const { error } =
        props.type === 'new'
          ? await createAddress(data)
          : await updateAddress({ ...data, id: props.preData.id });
      if (!error) {
        queryClient.invalidateQueries({
          queryKey: getQueryKey(trpc.address.listAllAddresses),
        });
        props.setOpen(false);
        form.reset();
        toast({
          title: `${props.type === 'new' ? '创建' : '更新'}成功`,
        });
      } else
        toast({
          variant: 'destructive',
          title: error.message,
        });
    });
  };
  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>姓名</FormLabel>
              <FormControl>
                <Input placeholder="姓名" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="phone"
          render={({ field }) => (
            <FormItem>
              <FormLabel>电话</FormLabel>
              <FormControl>
                <Input placeholder="电话" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <PoiSearchFormItem<typeof addressSchema>
          control={form.control}
          name="address"
          label="地址"
        />
        <div className="flex justify-between pt-3">
          <Button
            type="button"
            variant="outline"
            onClick={() => {
              props.setOpen(false);
              form.reset();
            }}
          >
            取消
          </Button>
          <Button disabled={isPending} type="submit">
            {isPending && <span className="i-ri-loader-4-line animate-spin" />}
            {props.type === 'new' ? '创建' : '更新'}
          </Button>
        </div>
      </form>
    </Form>
  );
};

export default function CreateEditAddress(
  props: CreateAddressProps | EditAddressProps,
) {
  const [open, setOpen] = useState(false);

  return (
    <Dialog open={open}>
      <DialogTrigger asChild>
        <div onClick={() => setOpen(true)}>{props.button}</div>
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>
            {props.type === 'new' ? '新增地址' : '编辑地址'}
          </DialogTitle>
          <DialogDescription>
            {props.type === 'new'
              ? '请填写以下信息以创建新的地址'
              : '请填写以下信息以编辑地址'}
          </DialogDescription>
        </DialogHeader>
        <AddressForm {...props} setOpen={setOpen} />
      </DialogContent>
    </Dialog>
  );
}
